<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="800" height="500" style="border:1px solid #d3d3d3;"></canvas>
<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style and parameters ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2.5;
    ctx.font = 'bold 22px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    const cy = 250; // Vertical center of the diagram
    const cx = 400; // Horizontal center (position of the loop)
    const objectX = 100;
    const imageX = 700;
    const rayHeight = 70; // Represents the dimension 'b'
    const loopRx = 45; // Horizontal radius of the ellipse
    const loopRy = 100; // Vertical radius of the ellipse

    // --- Helper function for drawing arrowheads ---
    function drawArrowHead(ctx, fromX, fromY, toX, toY, headLength) {
        const dx = toX - fromX;
        const dy = toY - fromY;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(toX, toY);
        ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(toX, toY);
        ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }
    
    // --- Main Drawing ---

    // 1. Z-axis
    ctx.beginPath();
    ctx.moveTo(objectX - 50, cy);
    ctx.lineTo(imageX + 50, cy);
    ctx.stroke();
    drawArrowHead(ctx, imageX + 30, cy, imageX + 50, cy, 12);
    ctx.fillText('z', imageX + 65, cy);

    // 2. Rays from object to image
    ctx.beginPath();
    ctx.moveTo(objectX, cy);
    ctx.lineTo(cx, cy - rayHeight);
    ctx.lineTo(imageX, cy);
    ctx.moveTo(objectX, cy);
    ctx.lineTo(cx, cy + rayHeight);
    ctx.lineTo(imageX, cy);
    ctx.stroke();

    // 3. Loop (Ellipse)
    ctx.beginPath();
    ctx.ellipse(cx, cy, loopRx, loopRy, 0, 0, 2 * Math.PI);
    ctx.stroke();

    // 4. Current I arc and arrow
    // The current I flows counter-clockwise when viewed from the right.
    // The arrow is shown on the top part of the loop, pointing left.
    const arcStartAngle = -Math.PI / 2 + 0.9;
    const arcEndAngle = -Math.PI / 2 - 0.9;
    ctx.beginPath();
    ctx.ellipse(cx, cy, loopRx, loopRy, 0, arcStartAngle, arcEndAngle, true); // true for counter-clockwise
    ctx.stroke();
    // Arrowhead at the end of the arc
    const headAngle = arcEndAngle;
    const headX = cx + loopRx * Math.cos(headAngle);
    const headY = cy + loopRy * Math.sin(headAngle);
    const prevAngle = headAngle + 0.1; // For calculating the tangent direction
    const prevX = cx + loopRx * Math.cos(prevAngle);
    const prevY = cy + loopRy * Math.sin(prevAngle);
    drawArrowHead(ctx, prevX, prevY, headX, headY, 15);
    // Label I
    ctx.fillText('I', cx + 25, cy - loopRy - 10);

    // 5. Dimension lines and labels
    const dimY = cy + 80;
    const tickHeight = 10;
    
    // l₀
    ctx.beginPath();
    ctx.moveTo(objectX, dimY);
    ctx.lineTo(cx, dimY);
    ctx.moveTo(objectX, dimY - tickHeight / 2);
    ctx.lineTo(objectX, dimY + tickHeight / 2);
    ctx.moveTo(cx, dimY - tickHeight / 2);
    ctx.lineTo(cx, dimY + tickHeight / 2);
    ctx.stroke();
    ctx.fillText('l\u2080', (objectX + cx) / 2, dimY + 22);

    // l₁
    ctx.beginPath();
    ctx.moveTo(cx, dimY);
    ctx.lineTo(imageX, dimY);
    ctx.moveTo(cx, dimY - tickHeight / 2);
    ctx.lineTo(cx, dimY + tickHeight / 2);
    ctx.moveTo(imageX, dimY - tickHeight / 2);
    ctx.lineTo(imageX, dimY + tickHeight / 2);
    ctx.stroke();
    ctx.fillText('l\u2081', (cx + imageX) / 2, dimY + 22);
    
    // Label b
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.lineTo(cx, cy - rayHeight);
    ctx.stroke();
    ctx.save();
    ctx.textAlign = 'right';
    ctx.fillText('b', cx - 8, cy - rayHeight / 2);
    ctx.restore();

    // Center mark '+' on the axis
    const crossSize = 6;
    ctx.beginPath();
    ctx.moveTo(cx - crossSize, cy);
    ctx.lineTo(cx + crossSize, cy);
    ctx.moveTo(cx, cy - crossSize);
    ctx.lineTo(cx, cy + crossSize);
    ctx.stroke();

    // 6. Text labels
    ctx.fillText('object', objectX, cy - rayHeight - 20);
    ctx.fillText('image', imageX, cy - rayHeight - 20);
    ctx.fillText('Fig. 2.67', cx, canvas.height - 30);

</script>
</body>
</html>